package org.koon.web;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.DynaBean;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.bean.copier.ValueProvider;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.json.JSONUtil;
import org.koon.KooRequest;
import org.koon.Koon;
import org.koon.web.annotation.RequestBody;

import java.lang.annotation.Annotation;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;

public class ParameterBinder {


    public static Object[] bind(KooRequest kooRequest,Handler handler){
        Parameter[] parameters = handler.getParameters();
        Object[] args = new Object[parameters.length];
        A:for (int i = 0; i < parameters.length; i++) {
            Parameter parameter = parameters[i];
            Class<?> parameterType = parameter.getType();
            boolean simpleTypeOrArray = ClassUtil.isSimpleTypeOrArray(parameterType);
            if (simpleTypeOrArray){
                String name = parameter.getName();
                Object param = kooRequest.getParam(name);
                args[i] = param == null?null:Convert.convert(parameterType,param);
            }else {
                Annotation[][] parameterAnnotations = handler.getMethod().getParameterAnnotations();
                if (parameterAnnotations[i].length>0){
                    for (Annotation annotation : parameterAnnotations[i]) {
                        if (annotation instanceof RequestBody){
                            Object o = Koon.JSON_CONVERT.convertFrom(parameterType, kooRequest.getBody());
                            //Object o = JSONUtil.toBean(kooRequest.getBodyString(), parameterType);
                            args[i] = o;
                            continue A;
                        }
                    }
                }
                Object o = ReflectUtil.newInstance(parameterType);
                BeanUtil.fillBean(o,new ValueProvider<String>(){
                    @Override
                    public Object value(String key, Type valueType) {
                        return kooRequest.getParam(key);
                    }

                    @Override
                    public boolean containsKey(String key) {
                        return kooRequest.getParam(key) != null;
                    }
                },CopyOptions.create());
                args[i] = o;
            }
        }
        return args;
    }
}
